package com.example.demo.reflection;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @Author CHAS
 * 2024/8/22 20:54
 **/

public class reflection {

    //    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
//        Class clazz = A.class;
//        A a = (A) clazz.getDeclaredConstructor().newInstance();
//        Method declaredMethod = clazz.getDeclaredMethod("test");
//        declaredMethod.setAccessible(true);
//        declaredMethod.invoke(a);
//    }
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException {
        Person person = new Person("CHAS", 20);
        Field name = Class.forName("com.example.demo.reflection.Person").getDeclaredField("name");
        name.setAccessible(true);
        Class clazz = Class.forName("com.example.demo.reflection.Person");
        Class superclass = clazz.getSuperclass();
        System.out.println(name.get(person));
    }
}

class A {
    private void test() {
        System.out.println("A");
    }
}


class Parent {
    public String publicField = "parent_publicField";
    protected String protectField = "parent_protectField";
    String defaultField = "parent_defaultField";
    private String privateField = "parent_privateField";

}

class Son extends Parent {

}

class reflectTestExtend {

    public @interface Test {

    }

    @Test
    public static void main(String args[]) throws Exception {
        Class c1 = Class.forName("com.example.demo.reflection.Son");
        //获取父类私有属性值
        System.out.println(getFieldValue(c1.newInstance(), "privateField"));
    }

    public static Field getDeclaredField(Object obj, String fieldName) {
        Field field = null;
        Class c = obj.getClass();
        boolean flag = c != Object.class;
        for (; c != Object.class; c = c.getSuperclass()) {
            try {
                field = c.getDeclaredField(fieldName);
                field.setAccessible(true);
                return field;
            } catch (Exception e) {
//                System.out.println(1);
                //这里甚么都不要做！并且这里的异常必须这样写，不能抛出去。
                //如果这里的异常打印或者往外抛，则就不会执行c = c.getSuperclass(),最后就不会进入到父类中了
            }
        }
        return null;
    }

    public static Object getFieldValue(Object object, String fieldName) throws Exception {
        Field field = getDeclaredField(object, fieldName);
        return field.get(object);
    }
}

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
